﻿using MvvmCross.Platform;
using MvvmCross.Plugins.Messenger;
using System.Collections.Generic;

namespace Sidvall.UI
{
    public static class EventManager
    {
        #region Public Members

        public static bool IsEnabled { get; set; }

        #region Publish

        public static void Publish<TMessage>(TMessage message) where TMessage : MvxMessage
        {
            if (!IsEnabled)
                return;
            var messenger = Mvx.Resolve<IMvxMessenger>();
            messenger.Publish<TMessage>(message);
        }

        #endregion
        #region Subscribe

        public static System.IDisposable Subscribe<TMessage>(System.Action<TMessage> deliveryAction) where TMessage : MvxMessage
        {
            if (!IsEnabled)
                return null;
            var messenger = Mvx.Resolve<IMvxMessenger>();
            return messenger.Subscribe<TMessage>(deliveryAction);
        }
        public static IEnumerable<System.IDisposable> Subscribe<TMessage1, TMessage2>(System.Action<TMessage1> deliveryAction1, System.Action<TMessage2> deliveryAction2)
            where TMessage1 : MvxMessage
            where TMessage2 : MvxMessage
        {
            if (!IsEnabled)
                return null;
            var messenger = Mvx.Resolve<IMvxMessenger>();
            var item1 = messenger.Subscribe<TMessage1>(deliveryAction1);
            var item2 = messenger.Subscribe<TMessage2>(deliveryAction2);
            return new List<System.IDisposable> {
                item1,
                item2,
            };
        }
        public static IEnumerable<System.IDisposable> Subscribe<TMessage1, TMessage2, TMessage3>(System.Action<TMessage1> deliveryAction1, System.Action<TMessage2> deliveryAction2,
            System.Action<TMessage3> deliveryAction3)
            where TMessage1 : MvxMessage
            where TMessage2 : MvxMessage
            where TMessage3 : MvxMessage
        {
            if (!IsEnabled)
                return null;
            var messenger = Mvx.Resolve<IMvxMessenger>();
            var item1 = messenger.Subscribe<TMessage1>(deliveryAction1);
            var item2 = messenger.Subscribe<TMessage2>(deliveryAction2);
            var item3 = messenger.Subscribe<TMessage3>(deliveryAction3);
            return new List<System.IDisposable> {
                item1,
                item2,
                item3,
            };
        }
        public static IEnumerable<System.IDisposable> Subscribe<TMessage1, TMessage2, TMessage3, TMessage4>(System.Action<TMessage1> deliveryAction1, System.Action<TMessage2> deliveryAction2,
            System.Action<TMessage3> deliveryAction3, System.Action<TMessage4> deliveryAction4)
            where TMessage1 : MvxMessage
            where TMessage2 : MvxMessage
            where TMessage3 : MvxMessage
            where TMessage4 : MvxMessage
        {
            if (!IsEnabled)
                return null;
            var messenger = Mvx.Resolve<IMvxMessenger>();
            var item1 = messenger.Subscribe<TMessage1>(deliveryAction1);
            var item2 = messenger.Subscribe<TMessage2>(deliveryAction2);
            var item3 = messenger.Subscribe<TMessage3>(deliveryAction3);
            var item4 = messenger.Subscribe<TMessage4>(deliveryAction4);
            return new List<System.IDisposable> {
                item1,
                item2,
                item3,
                item4,
            };
        }

        #endregion
        #region SubscribeOnMainThread

        public static System.IDisposable SubscribeOnMainThread<TMessage>(System.Action<TMessage> deliveryAction) where TMessage : MvxMessage
        {
            if (!IsEnabled)
                return null;
            var messenger = Mvx.Resolve<IMvxMessenger>();
            return messenger.SubscribeOnMainThread<TMessage>(deliveryAction);
        }
        public static IEnumerable<System.IDisposable> SubscribeOnMainThread<TMessage1, TMessage2>(System.Action<TMessage1> deliveryAction1, System.Action<TMessage2> deliveryAction2)
            where TMessage1 : MvxMessage
            where TMessage2 : MvxMessage
        {
            if (!IsEnabled)
                return null;
            var messenger = Mvx.Resolve<IMvxMessenger>();
            var item1 = messenger.SubscribeOnMainThread<TMessage1>(deliveryAction1);
            var item2 = messenger.SubscribeOnMainThread<TMessage2>(deliveryAction2);
            return new List<System.IDisposable> {
                item1,
                item2,
            };
        }
        public static IEnumerable<System.IDisposable> SubscribeOnMainThread<TMessage1, TMessage2, TMessage3>(System.Action<TMessage1> deliveryAction1, System.Action<TMessage2> deliveryAction2,
            System.Action<TMessage3> deliveryAction3)
            where TMessage1 : MvxMessage
            where TMessage2 : MvxMessage
            where TMessage3 : MvxMessage
        {
            if (!IsEnabled)
                return null;
            var messenger = Mvx.Resolve<IMvxMessenger>();
            var item1 = messenger.SubscribeOnMainThread<TMessage1>(deliveryAction1);
            var item2 = messenger.SubscribeOnMainThread<TMessage2>(deliveryAction2);
            var item3 = messenger.SubscribeOnMainThread<TMessage3>(deliveryAction3);
            return new List<System.IDisposable> {
                item1,
                item2,
                item3,
            };
        }
        public static IEnumerable<System.IDisposable> SubscribeOnMainThread<TMessage1, TMessage2, TMessage3, TMessage4>(System.Action<TMessage1> deliveryAction1, System.Action<TMessage2> deliveryAction2,
            System.Action<TMessage3> deliveryAction3, System.Action<TMessage4> deliveryAction4)
            where TMessage1 : MvxMessage
            where TMessage2 : MvxMessage
            where TMessage3 : MvxMessage
            where TMessage4 : MvxMessage
        {
            if (!IsEnabled)
                return null;
            var messenger = Mvx.Resolve<IMvxMessenger>();
            var item1 = messenger.SubscribeOnMainThread<TMessage1>(deliveryAction1);
            var item2 = messenger.SubscribeOnMainThread<TMessage2>(deliveryAction2);
            var item3 = messenger.SubscribeOnMainThread<TMessage3>(deliveryAction3);
            var item4 = messenger.SubscribeOnMainThread<TMessage4>(deliveryAction4);
            return new List<System.IDisposable> {
                item1,
                item2,
                item3,
                item4,
            };
        }

        #endregion
        #region Unsubscribe

        public static void Unsubscribe<TMessage>(System.IDisposable subscriptionToken) where TMessage : MvxMessage
        {
            if (!IsEnabled)
                return;
            var token = subscriptionToken as MvxSubscriptionToken;
            if (token == null)
                return;
            var messenger = Mvx.Resolve<IMvxMessenger>();
            messenger.Unsubscribe<TMessage>(token);
        }

        #endregion

        #endregion
    }
}
